#include "wx/wxprec.h"

#if wxUSE_STATBOX

#include "wx/statbox.h"
#include "wx/gtk/private.h"
#include "gdk/gdk.h"
#include "gtk/gtk.h"


#define LABEL_PAD 1
#define LABEL_SIDE_PAD 2

extern "C" {

  static void
  gtk_frame_size_allocate( GtkWidget     *widget,
                           GtkAllocation *allocation,
                           wxStaticBox *p ) {
    GtkFrame *frame = GTK_FRAME( widget );
    // this handler gets called _after_ the GTK+'s own signal handler; thus we
    // need to fix only the width of the GtkLabel
    // (everything else has already been handled by the GTK+ signal handler).
    if( frame->label_widget && GTK_WIDGET_VISIBLE( frame->label_widget ) ) {
      GtkAllocation ca = frame->label_widget->allocation;
      // we want the GtkLabel to not exceed maxWidth:
      int maxWidth = allocation->width - 2 * LABEL_SIDE_PAD - 2 * LABEL_PAD;
      maxWidth = wxMax( 2, maxWidth );    // maxWidth must always be positive!
      // truncate the label to the GtkFrame width...
      ca.width = wxMin( ca.width, maxWidth );
      gtk_widget_size_allocate( frame->label_widget, &ca );
    }
  }

}

IMPLEMENT_DYNAMIC_CLASS( wxStaticBox, wxControl )

wxStaticBox::wxStaticBox() {
}

wxStaticBox::wxStaticBox( wxWindow *parent,
                          wxWindowID id,
                          const wxString &label,
                          const wxPoint& pos,
                          const wxSize& size,
                          long style,
                          const wxString& name ) {
  Create( parent, id, label, pos, size, style, name );
}

bool wxStaticBox::Create( wxWindow *parent,
                          wxWindowID id,
                          const wxString& label,
                          const wxPoint& pos,
                          const wxSize& size,
                          long style,
                          const wxString& name ) {
  m_needParent = TRUE;
  if( !PreCreation( parent, pos, size ) ||
      !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ) ) {
    wxFAIL_MSG( wxT( "wxStaticBox creation failed" ) );
    return FALSE;
  }
  m_widget = GTKCreateFrame( label );
  wxControl::SetLabel( label );
  m_parent->DoAddChild( this );
  PostCreation( size );
  gfloat xalign;
  if( style & wxALIGN_CENTER ) {
    xalign = 0.5;
  } else if( style & wxALIGN_RIGHT ) {
    xalign = 1.0;
  } else  {
    xalign = 0.0;
  }
  if( style & ( wxALIGN_RIGHT | wxALIGN_CENTER ) ) // left alignment is default
  { gtk_frame_set_label_align( GTK_FRAME( m_widget ), xalign, 0.5 ); }
  g_signal_connect_after( m_widget, "size_allocate",
                          G_CALLBACK( gtk_frame_size_allocate ), this );
  return TRUE;
}

void wxStaticBox::SetLabel( const wxString& label ) {
  wxCHECK_RET( m_widget != NULL, wxT( "invalid staticbox" ) );
  GTKSetLabelForFrame( GTK_FRAME( m_widget ), label );
}

void wxStaticBox::DoApplyWidgetStyle( GtkRcStyle *style ) {
  GTKFrameApplyWidgetStyle( GTK_FRAME( m_widget ), style );
}

bool wxStaticBox::GTKWidgetNeedsMnemonic() const {
  return true;
}

void wxStaticBox::GTKWidgetDoSetMnemonic( GtkWidget* w ) {
  GTKFrameSetMnemonicWidget( GTK_FRAME( m_widget ), w );
}

wxVisualAttributes wxStaticBox::GetClassDefaultAttributes( wxWindowVariant ( variant ) ) {
  return GetDefaultAttributesFromGTKWidget( gtk_frame_new );
}


void wxStaticBox::GetBordersForSizer( int *borderTop, int *borderOther ) const {
  const int BORDER = 5;
  *borderTop = GetLabel().empty() ? 2 * BORDER : GetCharHeight();
  *borderOther = BORDER;
}

#endif
